package com.chuangdun.flutter.plugin.bubble

import android.app.ActivityManager
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.PixelFormat
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import androidx.core.app.NotificationCompat

class BubbleService : Service() {
    companion object {
        private const val TAG = "BubbleService"
        // 检查间隔
        private const val APP_STATE_CHECK_INTERVAL = 3000L 
        // 初始延迟
        private const val INITIAL_DELAY = 5000L 
        // 通知常量
        private const val NOTIFICATION_ID = 10026
        private const val DEFAULT_NOTIFICATION_CHANNEL_ID = "core_service"
        private const val DEFAULT_NOTIFICATION_CHANNEL_NAME = "核心服务"
        private const val DEFAULT_NOTIFICATION_TITLE = "悬浮窗服务"
        private const val DEFAULT_NOTIFICATION_CONTENT = "悬浮窗服务正在运行中..."
        private const val DEFAULT_NOTIFICATION_DESCRIPTION = "保持悬浮球在后台运行"
        // SharedPreferences常量
        private const val PREFS_NAME = "bubble_position"
        private const val KEY_BUBBLE_X = "bubble_x"
        private const val KEY_BUBBLE_Y = "bubble_y"
        // PendingIntent的通用Flag
        fun getPendingIntentFlags(): Int = 
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
            else 
                PendingIntent.FLAG_UPDATE_CURRENT
    }

    private lateinit var windowManager: WindowManager
    private lateinit var bubbleView: View
    private lateinit var layoutParams: WindowManager.LayoutParams
    private lateinit var sharedPrefs: SharedPreferences

    // 状态和坐标变量
    private var isBubbleVisible = false
    private val handler = Handler(Looper.getMainLooper())
    private var appStateCheckRunnable: Runnable? = null
    private var isServiceInitialized = false

    // 触摸交互变量
    private var initialX = 0
    private var initialY = 0
    private var initialTouchX = 0f
    private var initialTouchY = 0f


    override fun onBind(intent: Intent?): IBinder? = null

    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "创建前台服务")
        windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        sharedPrefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
        setupBubble()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        // 创建前台服务通知
        Log.d(TAG, "创建前台服务通知")
        createNotificationChannel()
        val notification = createNotification()
        startForeground(NOTIFICATION_ID, notification)
        
        return START_STICKY
    }

    /**
     * 保存悬浮球位置到SharedPreferences
     */
    private fun saveBubblePosition(x: Int, y: Int) {
        sharedPrefs.edit().apply {
            putInt(KEY_BUBBLE_X, x)
            putInt(KEY_BUBBLE_Y, y)
            apply()
        }
        Log.d(TAG, "保存悬浮球位置: ($x, $y)")
    }

    /**
     * 从SharedPreferences读取悬浮球位置
     * @return Pair<Int, Int> 位置坐标，如果没有保存过则返回null
     */
    private fun getSavedBubblePosition(): Pair<Int, Int>? {
        if (!sharedPrefs.contains(KEY_BUBBLE_X) || !sharedPrefs.contains(KEY_BUBBLE_Y)) {
            Log.d(TAG, "没有保存的悬浮球位置")
            return null
        }
        
        val x = sharedPrefs.getInt(KEY_BUBBLE_X, -1)
        val y = sharedPrefs.getInt(KEY_BUBBLE_Y, -1)
        Log.d(TAG, "读取保存的悬浮球位置: ($x, $y)")
        return Pair(x, y)
    }

    private fun setupBubble() {
        Log.d(TAG, "开始设置悬浮球")
        try {
            // 获取应用包名
            val packageName = packageName
            
            // 优先使用应用提供的布局文件，如果没有则使用插件默认布局
            val layoutResId = try {
                // 尝试获取应用中的bubble_layout.xml
                val appLayoutResId = resources.getIdentifier("bubble_layout", "layout", packageName)
                if (appLayoutResId != 0) {
                    Log.d(TAG, "使用应用提供的布局文件: $packageName/bubble_layout")
                    appLayoutResId
                } else {
                    Log.d(TAG, "使用插件默认布局文件")
                    R.layout.bubble_layout
                }
            } catch (e: Exception) {
                Log.w(TAG, "获取应用布局文件失败，使用默认布局: ${e.message}")
                R.layout.bubble_layout
            }
            
            // 创建悬浮球视图
            bubbleView = LayoutInflater.from(this).inflate(layoutResId, null)
            Log.d(TAG, "悬浮球视图创建成功")

            // 设置悬浮球参数 - 针对Android 10+优化
            layoutParams = WindowManager.LayoutParams().apply {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
                } else {
                    type = WindowManager.LayoutParams.TYPE_PHONE
                }
                format = PixelFormat.TRANSLUCENT
                flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or 
                       WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
                       WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                gravity = Gravity.TOP or Gravity.LEFT
                width = WindowManager.LayoutParams.WRAP_CONTENT
                height = WindowManager.LayoutParams.WRAP_CONTENT
                
                // 获取屏幕尺寸来设置默认位置
                val displayMetrics = resources.displayMetrics
                val screenHeight = displayMetrics.heightPixels
                val screenWidth = displayMetrics.widthPixels
                
                // 读取保存的位置，如果没有保存过则使用默认位置
                val savedPosition = getSavedBubblePosition()
                if (savedPosition != null) {
                    // 使用保存的位置
                    x = savedPosition.first
                    y = savedPosition.second
                    Log.d(TAG, "使用保存的悬浮球位置: ($x, $y)")
                } else {
                    // 设置默认位置：左侧垂直居中
                    // 确保悬浮窗至少一半宽度在屏幕内
                                    // 实时测量并设置悬浮窗位置
                bubbleView.post {
                    val measuredWidth = bubbleView.measuredWidth
                    val measuredHeight = bubbleView.measuredHeight
                    
                    if (measuredWidth > 0 && measuredHeight > 0) {
                        // 仅显示半宽度在屏幕右侧
                        layoutParams.x = screenWidth - measuredWidth / 2
                        layoutParams.y = (screenHeight - measuredHeight) / 2
                        
                        windowManager.updateViewLayout(bubbleView, layoutParams)
                        Log.d(TAG, "测量到的悬浮窗大小: $measuredWidth x $measuredHeight")
                    }
                }
                    y = (screenHeight / 2) - 50  // 垂直居中，减去50像素作为悬浮球高度的一半估算值
                    Log.d(TAG, "使用默认悬浮球位置: ($x, $y)")
                }
                
                Log.d(TAG, "屏幕尺寸: ${screenWidth}x${screenHeight}, 悬浮球位置: ($x, $y)")
            }
            Log.d(TAG, "悬浮球参数设置完成")

            // 设置触摸和点击事件
            setupBubbleInteraction()
            Log.d(TAG, "悬浮球交互设置完成")

            // 显示悬浮球
            windowManager.addView(bubbleView, layoutParams)
            isBubbleVisible = true
            isServiceInitialized = true
            Log.d(TAG, "悬浮球显示成功")
            
            // 延迟5秒后开始检查APP前后台状态，给用户时间切换到后台
            handler.postDelayed({
                Log.d(TAG, "开始启动APP前后台状态监控")
                startAppStateMonitoring()
            }, 5000)
            
        } catch (e: Exception) {
            Log.e(TAG, "设置悬浮球时出错: ${e.message}", e)
        }
    }

    private fun setupBubbleInteraction() {
        var isDragging = false
        var hasMoved = false
        val touchSlop = 10 // 触摸阈值，小于此值认为是点击而非拖拽

        // 使用OnTouchListener同时处理点击和拖拽事件
        bubbleView.setOnTouchListener { _, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    initialX = layoutParams.x
                    initialY = layoutParams.y
                    initialTouchX = event.rawX
                    initialTouchY = event.rawY
                    isDragging = false
                    hasMoved = false
                    true
                }
                MotionEvent.ACTION_MOVE -> {
                    val deltaX = Math.abs(event.rawX - initialTouchX)
                    val deltaY = Math.abs(event.rawY - initialTouchY)
                    
                    // 如果移动距离超过阈值，则认为是拖拽
                    if (deltaX > touchSlop || deltaY > touchSlop) {
                        isDragging = true
                        hasMoved = true
                        // 计算新的x和y坐标
                        val newX = initialX + (event.rawX - initialTouchX).toInt()
                        val newY = initialY + (event.rawY - initialTouchY).toInt()
                        
                        // 获取屏幕尺寸
                        val displayMetrics = resources.displayMetrics
                        val screenWidth = displayMetrics.widthPixels
                        val screenHeight = displayMetrics.heightPixels
                        
                        // 计算悬浮窗的实际宽度和高度
                        val bubbleWidth = bubbleView.width
                        val bubbleHeight = bubbleView.height
                        
                        // 限制x坐标：确保至少一半宽度在屏幕内
                        layoutParams.x = newX.coerceIn(
                            -(bubbleWidth / 2), 
                            screenWidth - bubbleWidth / 2
                        )
                        
                        // 限制y坐标：确保至少一半高度在屏幕内
                        layoutParams.y = newY.coerceIn(
                            -(bubbleHeight / 2), 
                            screenHeight - bubbleHeight / 2
                        )
                        
                        windowManager.updateViewLayout(bubbleView, layoutParams)
                    }
                    true
                }
                MotionEvent.ACTION_UP -> {
                    // 如果没有拖拽，则认为是点击事件
                    if (!hasMoved) {
                        Log.d(TAG, "点击悬浮球, 将应用拉到前台")
                        bringAppToForeground()
                    } else {
                        // 如果发生了拖拽，保存新的位置
                        saveBubblePosition(layoutParams.x, layoutParams.y)
                        Log.d(TAG, "拖拽结束，保存新位置: (${layoutParams.x}, ${layoutParams.y})")
                    }
                    isDragging = false
                    hasMoved = false
                    true
                }
                else -> false
            }
        }
    }

    /**
     * 创建启动应用的Intent
     */
    private fun createLaunchIntent(): Intent? {
        val packageName = packageName
        val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
        return launchIntent?.apply {
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
            setPackage(packageName)
        }
    }

    /**
     * 创建PendingIntent
     */
    private fun createPendingIntent(intent: Intent?): PendingIntent? {
        return intent?.let { 
            PendingIntent.getActivity(
                this,
                System.currentTimeMillis().toInt(),
                it,
                getPendingIntentFlags()
            )
        }
    }

    /**
     * 将应用拉到前台的主方法
     */
    private fun bringAppToForeground() {
        try {
            // Android 15+ 优先方法
            if (Build.VERSION.SDK_INT >= 35) {
                if (bringAppToForegroundAndroid15()) return
            }

            // 使用备用方法
            if (bringAppToForegroundViaAppTasks()) return

            // 降级方法：使用Intent
            val launchIntent = createLaunchIntent()
            launchIntent?.let { startActivity(it) }

        } catch (e: Exception) {
            Log.e(TAG, "将应用拉到前台时发生错误", e)
        }
    }

    /**
     * Android 15+ 将应用拉到前台
     */
    private fun bringAppToForegroundAndroid15(): Boolean {
        val launchIntent = createLaunchIntent()
        val pendingIntent = createPendingIntent(launchIntent)

        return try {
            pendingIntent?.send()
            true
        } catch (e: Exception) {
            Log.w(TAG, "Android 15+ PendingIntent方法失败", e)
            false
        }
    }

    /**
     * 通过AppTasks将应用拉到前台
     */
    private fun bringAppToForegroundViaAppTasks(): Boolean {
        return try {
            val am = getSystemService(ACTIVITY_SERVICE) as ActivityManager
            val appTasks = am.appTasks

            // 先尝试找匹配的应用任务
            appTasks.find { it.taskInfo.baseActivity?.packageName == packageName }?.moveToFront()
            // 如果没有找到，尝试第一个任务
                ?: appTasks.firstOrNull()?.moveToFront()

            true
        } catch (e: Exception) {
            Log.w(TAG, "AppTasks方法失败", e)
            false
        }
    }

    private fun showBringToForegroundNotification() {
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        
        // 创建点击通知时打开应用的意图
        val openAppIntent = packageManager.getLaunchIntentForPackage(packageName)
        openAppIntent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
        
        val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        } else {
            PendingIntent.FLAG_UPDATE_CURRENT
        }
        
        val pendingIntent = PendingIntent.getActivity(
            this,
            System.currentTimeMillis().toInt(),
            openAppIntent,
            flags
        )
        
        val notification = NotificationCompat.Builder(this, DEFAULT_NOTIFICATION_CHANNEL_ID)
            .setContentTitle(DEFAULT_NOTIFICATION_TITLE)
            .setContentText(DEFAULT_NOTIFICATION_CONTENT)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setOngoing(true)
            .build()
        notificationManager.notify(System.currentTimeMillis().toInt(), notification)
        Log.d(TAG, "前台通知已显示")
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                DEFAULT_NOTIFICATION_CHANNEL_ID,
                DEFAULT_NOTIFICATION_CHANNEL_NAME,
                NotificationManager.IMPORTANCE_DEFAULT
            )
            channel.description = DEFAULT_NOTIFICATION_DESCRIPTION
            channel.setSound(null, Notification.AUDIO_ATTRIBUTES_DEFAULT)
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun createNotification(): Notification {
        // 创建点击通知时打开应用的意图
        val openAppIntent = packageManager.getLaunchIntentForPackage(packageName)
        val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            android.app.PendingIntent.FLAG_IMMUTABLE or android.app.PendingIntent.FLAG_UPDATE_CURRENT
        } else {
            android.app.PendingIntent.FLAG_UPDATE_CURRENT
        }
        val pendingIntent = android.app.PendingIntent.getActivity(
            this,
            10003,
            openAppIntent,
            flags
        )
        return NotificationCompat.Builder(this, DEFAULT_NOTIFICATION_CHANNEL_ID)
            .setContentTitle(DEFAULT_NOTIFICATION_TITLE)
            .setContentText(DEFAULT_NOTIFICATION_CONTENT)
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setStyle(NotificationCompat.BigTextStyle())
            .setOngoing(true)
            .setAutoCancel(false)
            .build()
    }

    /**
     * 开始监控APP前后台状态
     */
    private fun startAppStateMonitoring() {
        appStateCheckRunnable = object : Runnable {
            override fun run() {
                try {
                    checkAndUpdateBubbleVisibility()
                } catch (e: Exception) {
                    Log.e(TAG, "监控APP状态时发生错误", e)
                } finally {
                    // 使用常量控制检查间隔
                    handler.postDelayed(this, APP_STATE_CHECK_INTERVAL)
                }
            }
        }
        handler.post(appStateCheckRunnable!!)
    }
    
    /**
     * 检查APP状态并更新悬浮球显示/隐藏
     */
    private fun checkAndUpdateBubbleVisibility() {
        val isAppInForeground = isAppInForeground()
        Log.d(TAG, "APP前台状态: $isAppInForeground, 悬浮球显示状态: $isBubbleVisible")
        
        if (isAppInForeground && isBubbleVisible) {
            // APP在前台且悬浮球可见时，隐藏悬浮球
            hideBubbleView()
        } else if (!isAppInForeground && !isBubbleVisible) {
            // APP在后台且悬浮球不可见时，显示悬浮球
            showBubbleView()
        }
    }
    
    /**
     * 检查APP是否在前台 - 简化版本
     */
    private fun isAppInForeground(): Boolean {
        try {
            val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
            val packageName = packageName
            
            // 使用getRunningAppProcesses检查前台进程
            val runningAppProcesses = activityManager.runningAppProcesses
            if (runningAppProcesses != null) {
                for (processInfo in runningAppProcesses) {
                    if (processInfo.processName == packageName) {
                        val isInForeground = processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                        Log.d(TAG, "进程: ${processInfo.processName}, 重要级: ${processInfo.importance}, 前台: $isInForeground")
                        if (isInForeground) {
                            return true
                        }
                    }
                }
            }
            
        } catch (e: Exception) {
            Log.e(TAG, "检查APP前台状态时出错: ${e.message}")
        }
        
        return false
    }
    
    /**
     * 显示悬浮球
     */
    private fun showBubbleView() {
        if (!isBubbleVisible && ::bubbleView.isInitialized) {
            try {
                bubbleView.visibility = View.VISIBLE
                isBubbleVisible = true
                Log.d(TAG, "悬浮球已显示")
            } catch (e: Exception) {
                Log.e(TAG, "显示悬浮球时出错: ${e.message}")
            }
        }
    }
    
    /**
     * 隐藏悬浮球
     */
    private fun hideBubbleView() {
        if (isBubbleVisible && ::bubbleView.isInitialized) {
            try {
                bubbleView.visibility = View.GONE
                isBubbleVisible = false
                Log.d(TAG, "悬浮球已隐藏")
            } catch (e: Exception) {
                Log.e(TAG, "隐藏悬浮球时出错: ${e.message}")
            }
        }
    }
    
    override fun onDestroy() {
        super.onDestroy()
        // 停止状态监控
        appStateCheckRunnable?.let {
            handler.removeCallbacks(it)
        }
        
        if (::bubbleView.isInitialized && bubbleView.windowToken != null) {
            windowManager.removeView(bubbleView)
        }
    }
}